import React, { useEffect, useState, useRef } from 'react';
import { connect, Dispatch, getDvaApp } from 'umi';
import styles from './index.less';
import { useEffectOnce, useEvent } from 'react-use';
import { ConnectProps, ConnectState } from '@/models/connect';
import { Upload, Button, message, Dropdown, Select, InputNumber } from 'antd';
import { DownOutlined, UserOutlined } from '@ant-design/icons';
// import ColorPicker from '@/components/widgets/ColorPicker';
import { getGltfModels } from '@/services/bimServices';
import { glTF3DModelList as _glTF3DModelList } from './localModels';
import { jsapi, layerCreator, viewUtils, layerUtils } from '@/utils/arcgis';
// import { exhydratGraphicLayer, hydratGraphicLayer } from '../elementRender/localStore';
import { exhydratGraphicLayer, hydratGraphicLayer } from '../elementRender/onlineStore';

const { Option } = Select;

export interface CitySketchProps {}
interface ConnectedProps extends ConnectProps {
  isFullScreen: boolean;
  isGlobalProcessRender: boolean;
  userName: string;
  dispatch: Dispatch;
}

export const MODEL_LAYERID = 'CitySketchLayer';

const CitySketch: React.FC<CitySketchProps & ConnectedProps> = ({
  dispatch,
  isFullScreen,
  isGlobalProcessRender,
  userName,
}) => {
  const [elevationInfoModel, setElevationInfoModel] = useState('on-the-ground');
  const [offset, setOffset] = useState(0);
  const [selectedModelIndex, setSelectedModelIndex] = useState(-1);
  // sketch操作模型
  const [sketchViewModel, setSketchViewModel] = useState<null | __esri.SketchViewModel>(null);
  const iframeRef = useRef(null);

  const refreshIndex = useState(0);
  const [glTF3DModelList, setGlTF3DModelList] = useState(_glTF3DModelList);

  useEffectOnce(() => {
    let searchParams = new URLSearchParams(window.location.href);
    initialize(searchParams.get('i'));
  });

  useEffect(() => {
    if (refreshIndex[0] % 2) {
      return;
    }
    getGltfModels().then(({ data = [] }) => {
      setGlTF3DModelList([
        ..._glTF3DModelList,
        ...data.map(({ thumb: image, modelUrl: url, name: title, id }) => {
          return {
            image,
            url,
            id,
            title,
          };
        }),
      ]);
    });
    // }, []);
  }, [refreshIndex[0]]);

  useEffect(() => {
    const msg = JSON.stringify({
      userNames: 'test',
      // userNames: userName || 'test',
      uploadUrl: window.appcfg._servicesUrl + '/api/gltf-models/upload',
    });
    iframeRef.current.contentWindow.postMessage(msg, '*');
  }, [userName]);

  useEvent('message', e => {
    if (e.isTrusted) {
      return;
    }
    message.info(JSON.stringify(e));
    refreshIndex[1](e => e + 2);
  });

  useEffect(() => {
    if (sketchViewModel) {
      if (selectedModelIndex === -1) {
        return;
      }
      // if (selectedModelIndex === -1) {
      //   sketchViewModel.cancel();
      // } else {
      addModel(glTF3DModelList[selectedModelIndex].url);
      // }
    }
    if (selectedModelIndex !== -1 && !sketchViewModel) {
      message.info('绘制环境加载中请耐心等候');
    }
  }, [selectedModelIndex, sketchViewModel]);

  useEffect(() => {
    if (window.agsGlobal && window.agsGlobal.view) {
      const view = window.agsGlobal.view;
      const layer = view.map.findLayerById(MODEL_LAYERID);
      if (layer) {
        layer.elevationInfo = {
          model: elevationInfoModel,
          offset: offset,
        };
      }
    }
  }, [offset, elevationInfoModel]);

  //  添加模型
  const addModel = (url: string) => {
    if (sketchViewModel) {
      sketchViewModel.cancel();
      const symbolLayers = [
        {
          type: 'object',
          resource: {
            href: url,
          },
        },
      ];
      sketchViewModel.pointSymbol = {
        type: 'point-3d',
        symbolLayers: symbolLayers as any,
      } as any;
      sketchViewModel.create('point');
      sketchViewModel.on('create', function(event) {
        // if (event.state === 'complete') {
        //   addModel(glTF3DModelList[selectedModelIndex].url);
        // }
        if (event.state === 'complete') {
          console.log(event.graphic);
          sketchViewModel.update(event.graphic, { tool: 'transform' });
          setSelectedModelIndex(-1);
        }
      });
    }
  };

  async function initialize() {
    const [GraphicsLayer, SketchViewModel] = await jsapi.load([
      'esri/layers/GraphicsLayer',
      'esri/widgets/Sketch/SketchViewModel',
    ]);
    const view = await viewUtils.isViewReady();
    let sketchLayer = view.map.findLayerById(MODEL_LAYERID);
    if (!sketchLayer) {
      sketchLayer = new GraphicsLayer({
        id: MODEL_LAYERID,
        title: '城市小品图层',
        elevationInfo: { mode: elevationInfoModel },
      });
      let searchParams = new URLSearchParams(window.location.href);
      hydratGraphicLayer(sketchLayer, searchParams.get('i'));
      view.map.addMany([sketchLayer]);
    }

    const sketchViewModel_ = new SketchViewModel({
      layer: sketchLayer,
      defaultUpdateOptions: {
        tool: 'reshape',
      },
      view: view,
    });

    sketchViewModel_.on('create', function(event) {
      if (event.state === 'complete') {
        // addModel(glTF3DModelList[selectedModelIndex].url);
      }
    });
    sketchViewModel_.on('update', function(event) {
      if (event.state === 'complete' || event.state === 'cancel') {
        setSelectedModelIndex(-1);
      }
    });

    setSketchViewModel(sketchViewModel_);
  }

  async function handleClearLayerCLick() {
    const view = await viewUtils.isViewReady();
    const layer = view.map.findLayerById(MODEL_LAYERID);
    // const buildingLayer = layerUtils.getLayerByTitle(view, layerName);
    layer.removeAll();
  }
  async function handleSaveLayerCLick() {
    // const view = await viewUtils.isViewReady();
    // const layer = view.map.findLayerById(MODEL_LAYERID);
    let searchParams = new URLSearchParams(window.location.href);
    await exhydratGraphicLayer(MODEL_LAYERID, searchParams.get('i'));
    message.info('模型保存成功');
  }

  const getModelList = () => {
    return (
      <div className={styles.modelList}>
        {glTF3DModelList.map((item, index) => {
          return (
            <div
              className={`${styles.modelListItem} ${
                index === selectedModelIndex ? styles.selected : null
              }`}
              key={item.id}
              onClick={() => {
                selectedModelIndex === index
                  ? setSelectedModelIndex(-1)
                  : setSelectedModelIndex(index);
              }}
            >
              <img src={item.image} alt={item.title} />
            </div>
          );
        })}
      </div>
    );
  };

  return (
    <div className={styles.citySketch} style={{ position: 'absolute', top: 144, left: 24 }}>
      <div className="side-panel2" style={{ position: 'relative' }}>
        <div className="side-panel2-title">城市小品</div>
        <div className="side-panel2-body" style={{ padding: 16 }}>
          <div style={{ marginBottom: 16 }}>
            <Dropdown
              overlay={getModelList()}
              trigger={['click']}
              onVisibleChange={() => {
                refreshIndex[1](e => e + 1);
              }}
            >
              <Button type="dashed" className={styles.opacityBtn} block>
                <span>请选择城市小品类型 </span> <DownOutlined />
              </Button>
            </Dropdown>
          </div>
          <div className={styles.inputWrapItem}>
            <div className={styles.itemKey}>高程模式：</div>
            <div className={styles.itemInput}>
              <Select
                value={elevationInfoModel}
                style={{ width: 232 }}
                onChange={value => {
                  setElevationInfoModel(value);
                }}
              >
                <Option value="on-the-ground">地面上</Option>
                <Option value="absolute-height">绝对高程</Option>
                <Option value="relative-to-ground">相对地面</Option>
                <Option value="relative-to-scene">相对场景</Option>
              </Select>
            </div>
          </div>
          {elevationInfoModel !== 'on-the-ground' && (
            <div className={styles.inputWrapItem} style={{ marginBottom: '0px' }}>
              <div className={styles.itemKey}>偏移量：</div>
              <div className={styles.itemInput}>
                <InputNumber
                  min={0}
                  max={100000}
                  formatter={value => `${value} 米`}
                  defaultValue={0}
                  onChange={value => {
                    setOffset(value);
                  }}
                />
              </div>
            </div>
          )}
          <div style={{ width: '100%', display: 'flex', justifyContent: 'space-between' }}>
            <Button
              className={'c-btn2  '}
              style={{ width: '46%' }}
              type={'primary'}
              onClick={handleClearLayerCLick}
            >
              清除全部
            </Button>
            <Button
              className={'c-btn1  '}
              style={{ width: '46%' }}
              type={'primary'}
              onClick={handleSaveLayerCLick}
            >
              保存
            </Button>
          </div>
        </div>
      </div>

      <div className="side-panel2" style={{ position: 'relative', paddingTop: 20 }}>
        <div className="side-panel2-title"> 上传模型</div>
        <div
          className="side-panel2-body"
          style={{
            padding: '16px 34px',
            // , paddingBottom: 0
          }}
        >
          <iframe
            ref={iframeRef}
            src="./gltf_thumbnail/index.html"
            frameborder="0"
            style={{
              height: 400,
              width: 366,
              marginLeft: -33,
              background: 'transparent',
            }}
          />
        </div>
      </div>
    </div>
  );
};

export default connect(({ app }: ConnectState) => {
  const { isFullScreen, isGlobalProcessRender, userName } = app;
  return {
    isFullScreen,
    isGlobalProcessRender,
    userName,
  };
})(CitySketch);
